<template>
  <div class="comp-full-calendar">
    <!-- header pick month -->
    <calender-header
      :current-month="currentMonth"
      :first-day="firstDay"
      :locale="locale"
      @change="emitChangeMonth"
    >
      <div slot="header-left">
        <slot name="fc-header-left"> </slot>
      </div>

      <div slot="header-right">
        <slot name="fc-header-right"> </slot>
      </div>
    </calender-header>
    <!-- body display date day and events -->
    <div class="full-calendar-body" v-loading="ifLoading">
      <!-- 上方显示的星期显示表 -->
      <div class="weeks">
        <span class="week" v-for="(dayIndex, i) in 7" :key="i">
          {{ dayIndex | localeWeekDay(firstDay, locale) }}</span
        >
      </div>
      <div class="dates" ref="dates">
        <div class="dates-bg">
          <div class="week-row" v-for="(week, index) in currentDates" v-bind:key="index">
            <div
              class="day-cell"
              v-for="(day, weekIndex) in week"
              v-bind:key="weekIndex"
              :class="{ isBgray: day.Bgray }"
            ></div>
          </div>
        </div>

        <!-- absolute so we can make dynamic td -->
        <div class="dates-events">
          <div class="events-week" v-for="(week, index) in currentDates" :key="index">
            <div
              class="events-day"
              v-for="(day, indexWeek) in week"
              :key="indexWeek"
              track-by="$index"
              @mouseenter="DayEnter(day.date, $event)"
              @mouseleave="DayLeave(day.date, $event)"
            >
              <p class="day-number" :class="{ today: day.isToday, isCgray: !day.isCurMonth }">
                {{ day.monthDay }}
              </p>
              <!-- 事件的显示框 -->
              <div class="event-box">
                <calendar-event-card
                  :event="event"
                  :date="day.date"
                  :firstDay="firstDay"
                  v-for="(event, index) in day.events"
                  v-show="event.cellIndex <= eventLimit"
                  @click="eventClick"
                  :key="index"
                >
                  <template slot-scope="p">
                    <slot name="fc-event-card" :event="p.event"></slot>
                  </template>
                </calendar-event-card>
                <p
                  v-if="day.events.length > eventLimit"
                  class="more-link"
                  @click.stop="selectThisDay(day, $event)"
                >
                  + {{ day.events[day.events.length - 1].cellIndex - eventLimit }} more
                </p>
              </div>
              <template v-if="day.weekDay !== 5 && day.weekDay !== 6">
                <el-button
                  class="stopMeeting"
                  v-if="day.Bgray"
                  size="mini"
                  @click="restoreDiagnosis(day)"
                  :disabled="isBeforeToday(day)"
                  >开诊</el-button
                >
                <el-button
                  class="stopMeeting"
                  v-else
                  size="mini"
                  @click="stopDiagnosis(day)"
                  :disabled="isBeforeToday(day)"
                  >停诊</el-button
                >
              </template>
            </div>
          </div>
        </div>

        <!-- full events when click show more -->
        <div
          class="more-events"
          v-show="showMore"
          :style="{ left: morePos.left + 'px', top: morePos.top + 'px' }"
        >
          <div class="more-header">
            <span class="title">{{ moreTitle(selectDay.date) }}</span>
            <span class="close" @click.stop="showMore = false">x</span>
          </div>
          <div class="more-body">
            <ul class="body-list">
              <li
                v-for="(event, index) in selectDay.events"
                :key="index"
                v-show="event.isShow"
                class="body-item"
                @click="eventClick(event, $event)"
              >
                {{ event.title }}
              </li>
            </ul>
          </div>
        </div>

        <slot name="body-card"> </slot>
      </div>
    </div>
  </div>
</template>
<script>
import moment from 'moment'
import _ from 'lodash'
import CalendarEventCard from '@/templates/components/CalendarEventCard'
import CalenderHeader from '@/templates/components/CalenderHeader'

const dateFunc = {
  getMonthViewStartDate(date, firstDay) {
    const fDay = parseInt(firstDay, 10)
    const start = moment(date)
    const startOfMonth = moment(start.startOf('month'))

    start.subtract(startOfMonth.day(), 'days')

    if (startOfMonth.day() < fDay) {
      start.subtract(7, 'days')
    }

    start.add(fDay, 'days')

    return start
  },
  getMonthViewEndDate() {
    return this.getMonthViewStartDate().add(6, 'weeks')
  }
}

export default {
  name: 'CalenderFull',
  props: {
    events: {
      // events will be displayed on calendar
      type: Array,
      default: () => {}
    },
    locale: {
      type: String,
      default: 'zh'
    },
    firstDay: {
      type: Number || String,
      validator(val) {
        const res = parseInt(val, 10)
        return res >= 0 && res < 7
      },
      default: 0,
      lang: {
        type: String,
        default: 'zh'
      }
    }
  },
  components: {
    CalenderHeader,
    CalendarEventCard
  },
  mounted() {
    // console.log('nextMonth', moment().month(moment().month() + 1).format('YYYY-MM'));
    // console.log('preMonth', moment().month(moment().month() - 1).format('YYYY-MM'));
    this.emitChangeMonth(this.currentMonth)
    // this.getSchedulInfo(moment().get('year'), moment().get('month') + 1);
  },
  data() {
    return {
      preMonth: moment()
        .month(moment().month() - 1)
        .format('YYYY-MM'),
      nextMonth: moment()
        .month(moment().month() + 1)
        .format('YYYY-MM'),
      curMonth: moment()
        .month(moment().month())
        .format('YYYY-MM'),
      ifLoading: false,
      currentMonth: moment().startOf('month'),
      calenderData: [],
      preCalenderData: [],
      nextCalenderData: [],
      nowYear: '',
      nowMonth: '',
      isLismit: true,
      eventLimit: 3,
      showMore: false,
      morePos: {
        top: 0,
        left: 0
      },
      selectDay: {},
      refreshData: false
    }
  },
  computed: {
    currentDates() {
      if (this.refreshData) {
        console.log('happened')
        return this.getCalendar()
      }
      console.log('happened-2')
      return this.getCalendar()
    }
  },
  methods: {
    async getSchedulInfo(year, month) {
      // console.log('dateString', dateString);
      // const year = _.split(dateString._i, '年')[0];
      // const month = _.split(_.split(dateString._i, '年')[1], '月')[0];
      this.ifLoading = true
      console.log('year-month', year, month)
      let nY = ''
      let nM = ''
      if (!year) {
        nY = moment().get('year')
      } else {
        nY = year
      }
      if (!month) {
        nM = moment().get('month') + 1
      } else {
        nM = month
      }
      try {
        await this.$axios({
          // 详见 axios 请求配置项
          method: 'GET',
          url: `/scheduling?year=${nY}&month=${nM}`
        }).then(res => {
          // 请求失败
          if (res.data.code !== 200) {
            throw new Error(res.data)
          }
          // 请求成功
          const result = res.data.data.currSchedule
          const preresult = res.data.data.prevSchedule
          const nextresult = res.data.data.nextSchedule
          console.log('result', result, preresult, nextresult)
          this.calenderData = []
          this.preCalenderData = []
          this.nextCalenderData = []
          Object.keys(result).forEach(item => {
            this.calenderData.push(result[item])
          })
          Object.keys(preresult).forEach(item => {
            this.preCalenderData.push(preresult[item])
          })
          Object.keys(nextresult).forEach(item => {
            this.nextCalenderData.push(nextresult[item])
          })
        })
        this.ifLoading = false
      } catch (e) {
        // 跳出
      }
    },
    async changeSchedul(changeDay, status) {
      console.log('changeDay', changeDay)
      this.ifLoading = true
      try {
        await this.$axios({
          // 详见 axios 请求配置项
          method: 'PUT',
          url: `/scheduling/${changeDay}?status=${status}`
        }).then(res => {
          // 请求失败
          if (res.data.code !== 200) {
            throw new Error(res.data)
          }
          // 请求成功
          this.$message.success('修改排班信息成功')
          this.ifLoading = false
          this.getSchedulInfo(this.nowYear, this.nowMonth)
        })
      } catch (e) {
        // 跳出
      }
      // this.$forceUpdate();
    },
    isBeforeToday(day) {
      return day.date.isBefore(moment(new Date()))
    },
    restoreDiagnosis(day) {
      console.log('day', day)
      // let changeDay = '';
      // if (this.nowYear && this.nowMonth) {
      //   changeDay = this.nowYear + this.nowMonth + day.monthDay;
      // } else {
      //   changeDay = `${moment().get('year')}-${moment().get('month') + 1}-${day.monthDay}`;
      // }
      const date = moment(day.date._d).format('YYYY-MM-DD')
      this.changeSchedul(date, false)
      console.log('day.monthDay - 1', day, day.monthDay - 1, this.calenderData[day.monthDay - 1])
      this.calenderData[day.monthDay - 1] = false
      this.refreshData = !this.refreshData
    },
    stopDiagnosis(day) {
      const date = moment(day.date._d).format('YYYY-MM-DD')
      console.log('date', date)
      // let changeDay = '';
      // if (this.nowYear && this.nowMonth) {
      //   changeDay = this.nowYear + this.nowMonth + day.monthDay;
      // } else {
      //   changeDay = `${moment().get('year')}-${moment().get('month') + 1}-${day.monthDay}`;
      // }
      this.changeSchedul(date, true)
      console.log('day.monthDay - 1', day, day.monthDay - 1, this.calenderData[day.monthDay - 1])
      this.calenderData[day.monthDay - 1] = true
      this.refreshData = !this.refreshData
    },
    deletetip(jsevent) {
      console.log(jsevent.target.parentNode)
      // jsevent.target.parentNode.style.display = 'none';
    },
    getYear(dateString) {
      console.log('dateString', dateString)
      const year = _.split(dateString, '年')[0]
      return year
      // const month = _.split(_.split(dateString._i, '年')[1], '月')[0];
    },
    getMonth(dateString) {
      console.log('dateString', dateString)
      // const year = _.split(dateString._i, '年')[0];
      const month = _.split(_.split(dateString, '年')[1], '月')[0]
      return month
    },
    emitChangeMonth(firstDayOfMonth) {
      this.currentMonth = firstDayOfMonth
      this.nowYear = this.getYear(firstDayOfMonth._i)
      this.nowMonth = this.getMonth(firstDayOfMonth._i)

      const start = dateFunc.getMonthViewStartDate(firstDayOfMonth, this.firstDay)
      const end = dateFunc.getMonthViewEndDate(firstDayOfMonth, this.firstDay)
      console.log('start-end', firstDayOfMonth, start, end)
      this.getSchedulInfo(this.nowYear, this.nowMonth)
      this.$emit('changeMonth', start, end, firstDayOfMonth)
    },
    moreTitle(date) {
      if (!date) return ''
      return moment(date).format('ll')
    },
    fromatCalenderData() {
      console.log(
        'momnet-get-time',
        moment().format('YYYY-MM-DD'),
        moment('2020-01-1').format('YYYY-MM-DD')
      )
      const stopDate = []
      let Y = 0
      let M = 0
      let curM = ''
      let preM = ''
      let nextM = ''
      if (this.nowYear && this.nowMonth) {
        Y = parseInt(this.nowYear, 10)
        M = parseInt(this.nowMonth, 10) - 1
        curM = moment()
          .set({ year: Y, month: M })
          .format('YYYY-MM')
        preM = moment()
          .set({ year: Y, month: M - 1 })
          .format('YYYY-MM')
        nextM = moment()
          .set({ year: Y, month: M + 1 })
          .format('YYYY-MM')
      } else {
        curM = this.curMonth
        preM = this.preMonth
        nextM = this.nextMonth
      }
      for (let i = 0; i < this.calenderData.length; i++) {
        console.log(this.calenderData[i])
        if (this.calenderData[i] === true) {
          if (i < 9) {
            stopDate.push({ day: `${curM}-0${i + 1}` })
          } else {
            stopDate.push({ day: `${curM}-${i + 1}` })
          }
        }
      }
      for (let i = 0; i < this.preCalenderData.length; i++) {
        console.log(this.preCalenderData[i])
        if (this.preCalenderData[i] === true) {
          if (i < 9) {
            stopDate.push({ day: `${preM}-0${i + 1}` })
          } else {
            stopDate.push({ day: `${preM}-${i + 1}` })
          }
        }
      }
      for (let i = 0; i < this.nextCalenderData.length; i++) {
        console.log(this.nextCalenderData[i])
        if (this.nextCalenderData[i] === true) {
          console.log('nextCalenderData==true', i)
          if (i < 9) {
            stopDate.push({ day: `${nextM}-0${i + 1}` })
          } else {
            stopDate.push({ day: `${nextM}-${i + 1}` })
          }
        }
      }
      console.log('stopDate', stopDate)
      return stopDate
    },
    getCalendar() {
      // 获取数据库中停诊信息
      const calendar = []
      if (this.calenderData.length > 0) {
        const DataBasedate = this.fromatCalenderData()
        console.log('DataBasedate', DataBasedate)
        const templatesMap = new Map()
        if (typeof DataBasedate !== 'undefined') {
          DataBasedate.forEach(item => {
            templatesMap.set(item.day, item)
          })
        }
        console.log('templatesMap', templatesMap)
        // calculate 2d-array of each month
        const monthViewStartDate = dateFunc.getMonthViewStartDate(this.currentMonth, this.firstDay)
        monthViewStartDate.add(1, 'day')
        console.log('monthViewStartDate', monthViewStartDate)

        for (let perWeek = 0; perWeek < 6; perWeek++) {
          const week = []

          for (let perDay = 0; perDay < 7; perDay++) {
            week.push({
              monthDay: monthViewStartDate.date(),
              isToday: monthViewStartDate.isSame(moment(), 'day'),
              isCurMonth: monthViewStartDate.isSame(this.currentMonth, 'month'),
              weekDay: perDay,
              date: moment(monthViewStartDate),
              events: this.slotEvents(monthViewStartDate),
              Bgray: this.isBgray(monthViewStartDate, templatesMap)
            })

            monthViewStartDate.add(1, 'day')
          }
          console.log('week', week)
          calendar.push(week)
        }
      }
      this.ifLoading = false
      return calendar
    },
    isBgray(monthViewStartDate, templatesMap) {
      console.log('monthViewStartDate-isBgray', moment(monthViewStartDate._d).format('YYYY-MM-DD'))
      console.log('isBgray', templatesMap.has(moment(monthViewStartDate._d).format('YYYY-MM-DD')))
      if (templatesMap.has(moment(monthViewStartDate._d).format('YYYY-MM-DD'))) {
        return true
      }
      return false
    },
    slotEvents(date) {
      // find all events start from this date
      const thisDayEvents = this.events.filter(day => {
        const st = moment(day.start)
        const ed = moment(day.end ? day.end : st)

        return date.isBetween(st, ed, null, '[]')
      })

      // sort by duration
      thisDayEvents.sort((a, b) => {
        if (!a.cellIndex) return 1
        if (!b.cellIndex) return -1
        return a.cellIndex - b.cellIndex
      })

      // mark cellIndex and place holder
      for (let i = 0; i < thisDayEvents.length; i++) {
        thisDayEvents[i].cellIndex = thisDayEvents[i].cellIndex || i + 1
        thisDayEvents[i].isShow = true
        if (thisDayEvents[i].cellIndex === i + 1 || i > 2) {
          console.log()
        } else {
          thisDayEvents.splice(i, 0, {
            title: 'holder',
            cellIndex: i + 1,
            start: date.format(),
            end: date.format(),
            isShow: false
          })
        }
      }

      return thisDayEvents
    },
    selectThisDay(day, jsEvent) {
      this.selectDay = day
      this.showMore = true
      this.morePos = this.computePos(jsEvent.target)
      this.morePos.top -= 100
      const events = day.events.filter(item => item.isShow === true)
      this.$emit('moreClick', day.date, events, jsEvent)
    },
    computePos(target) {
      const eventRect = target.getBoundingClientRect()
      const pageRect = this.$refs.dates.getBoundingClientRect()
      return {
        left: eventRect.left - pageRect.left,
        top: eventRect.top + eventRect.height - pageRect.top
      }
    },
    // dayClick(day, jsEvent) {
    //     this.$emit("dayClick", day, jsEvent);
    // },
    DayEnter(day, jsEvent) {
      this.$emit('DayEnterFather', day, jsEvent)
    },
    DayLeave(day, jsEvent) {
      this.$emit('DayLeaveFather', day, jsEvent)
    },
    eventClick(event, jsEvent) {
      if (!event.isShow) return

      jsEvent.stopPropagation()
      const pos = this.computePos(jsEvent.target)
      this.$emit('eventClick', event, jsEvent, pos)
    }
  },
  filters: {
    localeWeekDay(weekday, firstDay, locale) {
      const fDay = parseInt(firstDay, 10)
      const localMoment = moment().locale(locale)
      return localMoment.localeData().weekdaysShort()[(weekday + fDay) % 7]
    }
  }
}
</script>
<style scoped>
.stopMeeting {
  margin-left: 65px;
  margin-bottom: 5px;
  position: absolute;
  bottom: 0;
}

.isBgray {
  background-color: #eeeeee;
  color: gray;
}

.isCgray {
  color: gray;
}

#RightAlert {
  width: 150px;
  height: 180px;
  border: 1px solid blue;
  background-color: #f9a101;
  position: absolute;
  top: 60px;
  left: 144px;
  z-index: 999999;
}

#RightAlert #Triangle {
  width: 0;
  height: 0;
  border-top: 10px solid transparent;
  border-right: 15px solid #f9a101;
  border-bottom: 10px solid transparent;
  position: absolute;
  top: 10px;
  left: -15px;
}

#RightAlert #DeleteTop {
  width: 30px;
  height: 30px;
  border: 1px solid blue;
  position: absolute;
  top: 0;
  right: 0;
  background-color: red;
}

.comp-full-calendar {
  padding: 20px;
  background: #fff;
  max-width: 960px;
  margin: 0 auto;
}

.comp-full-calendar ul,
.comp-full-calendar p {
  margin: 0;
  padding: 0;
}

.full-calendar-body {
  min-height: 800px;
  margin-top: 20px;
}

.full-calendar-body .weeks {
  display: flex;
  border-top: 1px solid #e0e0e0;
  border-bottom: 1px solid #e0e0e0;
  border-left: 1px solid #e0e0e0;
}

.full-calendar-body .weeks .week {
  flex: 1;
  text-align: center;
  border-right: 1px solid #e0e0e0;
}

.full-calendar-body .dates {
  position: relative;
}

.full-calendar-body .dates .week-row {
  border-left: 1px solid #e0e0e0;
  display: flex;
}

.full-calendar-body .dates .week-row .day-cell {
  flex: 1;
  min-height: 112px;
  padding: 4px;
  border-right: 1px solid #e0e0e0;
  border-bottom: 1px solid #e0e0e0;
}

.full-calendar-body .dates .week-row .day-cell .day-number {
  text-align: center;
  width: 25px;
  height: 25px;
  line-height: 25px;
  float: right;
  border-radius: 50%;
}

.full-calendar-body .dates .week-row .day-cell .today {
  background-color: red;
  color: #fff;
  z-index: 99999;
  box-shadow: 2px 2px 2px 2px #888888;
}

.full-calendar-body .dates .week-row .day-cell.not-cur-month .day-number {
  color: gray;
}

.full-calendar-body .dates .dates-events {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  width: 100%;
}

.full-calendar-body .dates .dates-events .events-week {
  display: flex;
}

.full-calendar-body .dates .dates-events .events-week .events-day {
  cursor: pointer;
  flex: 1;
  padding: 4px;
  min-height: 112px;
  overflow: hidden;
  text-overflow: ellipsis;
  position: relative;
}

.full-calendar-body .dates .dates-events .events-week .events-day .day-number {
  text-align: center;
  width: 25px;
  height: 25px;
  line-height: 25px;
  float: right;
  border-radius: 50%;
}

.full-calendar-body .dates .dates-events .events-week .events-day .today {
  background-color: red;
  color: #fff;
  z-index: 99999;
}

.full-calendar-body .dates .dates-events .events-week .events-day.not-cur-month .day-number {
  color: gray;
}

.full-calendar-body .dates .dates-events .events-week .events-day .event-box {
  padding-top: 26px;
}

.full-calendar-body .dates .dates-events .events-week .events-day .event-box .event-item {
  cursor: pointer;
  font-size: 12px;
  background-color: #c7e6fd;
  margin-bottom: 2px;
  color: rgba(0, 0, 0, 0.87);
  padding: 0 0 0 4px;
  height: 20px;
  line-height: 5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.full-calendar-body .dates .dates-events .events-week .events-day .event-box .event-item.is-start {
  margin-left: 4px;
}

.full-calendar-body .dates .dates-events .events-week .events-day .event-box .event-item.is-end {
  margin-right: 4px;
}

.full-calendar-body
  .dates
  .dates-events
  .events-week
  .events-day
  .event-box
  .event-item.is-opacity {
  opacity: 0;
}

.full-calendar-body .dates .dates-events .events-week .events-day .event-box .more-link {
  cursor: pointer;
  padding-left: 8px;
  padding-right: 2px;
  color: rgba(0, 0, 0, 0.38);
  font-size: 14px;
}

.full-calendar-body .dates .more-events {
  position: absolute;
  width: 150px;
  z-index: 2;
  border: 1px solid #eee;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
}

.full-calendar-body .dates .more-events .more-header {
  background-color: #eee;
  padding: 5px;
  display: flex;
  align-items: center;
  font-size: 14px;
}

.full-calendar-body .dates .more-events .more-header .title {
  flex: 1;
}

.full-calendar-body .dates .more-events .more-header .close {
  margin-right: 2px;
  cursor: pointer;
  font-size: 16px;
}

.full-calendar-body .dates .more-events .more-body {
  height: 146px;
  overflow: hidden;
}

.full-calendar-body .dates .more-events .more-body .body-list {
  height: 144px;
  padding: 5px;
  overflow: auto;
  background-color: #fff;
}

.full-calendar-body .dates .more-events .more-body .body-list .body-item {
  cursor: pointer;
  font-size: 12px;
  background-color: #c7e6fd;
  margin-bottom: 2px;
  color: rgba(0, 0, 0, 0.87);
  padding: 0 0 0 4px;
  height: 18px;
  line-height: 18px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.full-calendar-body .FirstGreen {
  background: green;
}

.full-calendar-body .FirstYellow {
  background: yellow;
}

.full-calendar-body .FirstRed {
  background: red;
}

.full-calendar-body .CircleData {
  width: 5px;
  height: 5px;
  border-radius: 100%;
  float: left;
  margin-top: 10px;
  margin-left: 10px;
}
</style>
